home *** CD-ROM | disk | FTP | other *** search
/ Aminet 7 / Aminet 7 - August 1995.iso / Aminet / docs / misc / ConcNews.lha / news / general.programming / comp.programming_1247_000009.msg < prev    next >
Encoding:
Text File  |  1994-11-27  |  4.6 KB  |  189 lines

  1. Path: dd.chalmers.se!news.chalmers.se!sunic!EU.net!howland.reston.ans.net!sol.ctr.columbia.edu!news.unomaha.edu!crcnis1.unl.edu!manager
  2. From: mgleason@cse.unl.edu (Mike Gleason)
  3. Newsgroups: comp.programming
  4. Subject: Re: Algorithm for finding all possible combinations
  5. Date: 30 Jan 1994 22:57:43 GMT
  6. Organization: NCEMRSoft
  7. Lines: 176
  8. Distribution: world
  9. Message-ID: <2ihe18$hqu@crcnis1.unl.edu>
  10. References: <2ighh8$g8f@nntp.hut.fi> <Jan.30.16.35.33.1994.13266@pegasus.rutgers.edu>
  11. NNTP-Posting-Host: cse.unl.edu
  12.  
  13. chiun@pegasus.rutgers.edu (Remo Williams) writes:
  14.  
  15. |>    I have three chunks of a data, named a, b and c. I need to
  16. |>    process them in every possible order. So I need to organize
  17. |>    them like this:
  18. |>        a b c
  19. |>        a c b
  20. |>        b a c
  21. |>        b c a
  22. |>        c a b
  23. |>        c b a
  24.  
  25. |Pseduocode:    z:=c
  26. |        for x:= a to c do
  27. |            for y:= b to c do
  28. |            if (x<y) and (y<z) do
  29. |            write (x,y,z)
  30. |            write (z,y,z)
  31.  
  32. That's swell, but I believe the original poster wanted something for
  33. the general case.
  34.  
  35. Here's a chunk of code I wrote last year for this purpose.  This is
  36. copyrighted code, but I don't mind what you use it for as long as
  37. you don't use it as your homework assignment:
  38.  
  39.  
  40. /* WeakPermDriver.c
  41.  * Copyright 1993 by Mike Gleason.
  42.  */
  43.  
  44. #include <stdio.h>
  45. #include <stdlib.h>
  46. #include <string.h>
  47.  
  48. #define DONE                (1)
  49. #define NOT_DONE            (0)
  50. #define DEFAULT_N            (4)
  51. #define MAXPERMSIZE            (32)
  52.  
  53. typedef int SetElement;
  54. typedef SetElement Permutation[MAXPERMSIZE];
  55.  
  56. static void PermToCycle(Permutation p, int permSize, char *cycle)
  57. {
  58.     int i, j;
  59.     Permutation used;
  60.     SetElement x, y, cstart;
  61.     int ncycles = 0;
  62.  
  63.     for (i=0; i<permSize; i++)
  64.         used[i] = 0;
  65.  
  66.     *cycle++ = '(';
  67.     x = 1;
  68.     used[x-1] = 1;
  69.     cstart = x;
  70.     *cycle++ = (char)(x + '0');
  71.  
  72.     for (;;) {
  73.         y = p[x-1];
  74.         if (y == cstart) {
  75.             /* End cycle. */
  76.             /* First get rid of any 1-cycles. */
  77.             if (cycle[-2] == '(')
  78.                 cycle -= 2;
  79.             else {
  80.                 *cycle++ = ')';
  81.                 ++ncycles;    /* Count 2-cycles, and larger. */
  82.             }
  83.             x = -1;
  84.             for (j=0; j<permSize; j++)
  85.                 if (used[j] == 0) {
  86.                     x = j + 1;
  87.                     cstart = x;
  88.                     used[j] = 1;
  89.                     *cycle++ = '(';
  90.                     *cycle++ = (char)(x + '0');
  91.                     break;
  92.                 }
  93.             if (x < 0)
  94.                 break;        
  95.         } else {
  96.             *cycle++ = (char)(y + '0');
  97.             used[y - 1] = 1;
  98.             x = y;
  99.         }
  100.     }
  101.     if (ncycles == 0)
  102.         *cycle++ = '1';        /* Must be identity cycles. */
  103.     *cycle = 0;
  104. }    /* PermToCycle */
  105.  
  106. static void PrintPerm(Permutation p, int permSize, int permNum)
  107. {
  108.     int i;
  109.     char cy[128];
  110.  
  111.     printf("%3d: ", permNum);
  112.     PermToCycle(p, permSize, cy);
  113.     for (i=0; i<permSize; i++)
  114.         printf("%d%c", p[i], (i == permSize - 1) ? ' ' : '-');
  115.     printf(" = %s\n", cy);
  116. }    /* PrintPerm */
  117.  
  118.  
  119.  
  120. static int NextPerm(Permutation p, int permSize)
  121. {
  122.     int i;
  123.     
  124.     /* First find where in the permutation the "largest" element is. */
  125.     for (i=0; p[i] != permSize; ) ++i;
  126.  
  127.     /* Check to see if that element is in the first position. */
  128.     if (i==0) {
  129.         /* If this element is in the first position, and the size of
  130.          * the (sub)permutation is only 1 element, there is no next
  131.          * permutation, so say we're finished.  We'll get to this point
  132.          * if the permutation we were asked to "next" was in descending
  133.          * order, and that one is the last one, therefore there is no
  134.          * next permutation.
  135.          */
  136.         if (permSize==1)
  137.             return DONE;
  138.  
  139.         /* Otherwise, shift all the other elements "back" one slot. */
  140.         memmove(p, p+1, (permSize - 1) * sizeof(SetElement));
  141.         
  142.         /* Recursively call myself to work on a smaller sub-permutation. */
  143.         if (NextPerm(p, permSize - 1) == DONE)
  144.             return DONE;
  145.             
  146.         /* Now stick the "largest" element in the last position. */
  147.         p[permSize - 1] = (SetElement) permSize;
  148.     } else {
  149.         p[i] = p[i-1];
  150.         p[i-1] = permSize;
  151.     }
  152.     return (NOT_DONE);
  153. }    /* NextPerm */
  154.  
  155.  
  156.  
  157. void main(int argc, char *argv[])
  158. {
  159.     int n = DEFAULT_N;    /* Number of elements in the set to permute. */
  160.     int permNum = 0;    /* Not the rank, since they're not computed
  161.                          * in ascending order.
  162.                          */
  163.     Permutation perm;    /* The set of elements. */
  164.     int i;
  165.  
  166.     /* Get the 'n' from the command line, if you specified one. */
  167.     if (argc > 1) {
  168.         i = atoi(argv[1]);
  169.         if ((i > 1) && (i <= MAXPERMSIZE))
  170.             n = i;
  171.     }
  172.  
  173.     /* Initialize the first permutation. */
  174.     for (i=0; i<n; i++)
  175.         perm[i] = i+1;
  176.     
  177.     /* Loop until we've found them all. */
  178.     do {
  179.         PrintPerm(perm, n, ++permNum);
  180.     } while (NextPerm(perm, n) == NOT_DONE);
  181.     
  182.     exit(0);
  183. }    /* main */
  184.  
  185. /* eof */
  186. --
  187. ______________________________________________________________________________
  188. mike gleason                 mgleason@cse.unl.edu             NCEMRSoft, baby!
  189.